#include "texture.h"
#include "init.h"
#include <SDL_image.h>

SDL_Texture *gTexture = NULL;

SDL_Texture* loadTexture(const char* imgPath){
    SDL_Texture *texture = NULL;
    SDL_Surface *surface = IMG_Load(imgPath);
    if(!surface){
        printf("Failed to load image %s: %s\n", imgPath, IMG_GetError());
    }else{
        texture = SDL_CreateTextureFromSurface(gRender, surface);
        if(!texture){
            printf("Failed to load image %s: %s\n", imgPath, SDL_GetError());
        }
        SDL_FreeSurface(surface);
    }
    return texture;
}

SDL_Texture* loadTextureEx(const char* imgPath, SDL_Renderer **renderer){
    SDL_Texture *texture = NULL;
    SDL_Surface *surface = IMG_Load(imgPath);
    if(!surface){
        printf("Failed to load image %s: %s\n", imgPath, IMG_GetError());
    }else{
        SDL_SetColorKey(surface, SDL_TRUE, SDL_MapRGB(surface->format, 0xff, 0xff, 0xff));
        texture = SDL_CreateTextureFromSurface(*renderer, surface);
        if(!texture){
            printf("Failed to load image %s: %s\n", imgPath, SDL_GetError());
        }
        SDL_FreeSurface(surface);
    }
    return texture;
}

SDL_Texture* loadTextureExRect(const char* imgPath, SDL_Renderer **renderer, SDL_Rect *srcRect){
    SDL_Texture *texture = NULL;
    SDL_Surface *surface = IMG_Load(imgPath);
    if(!surface){
        printf("Failed to load image %s: %s\n", imgPath, IMG_GetError());
    }else{
        SDL_SetColorKey(surface, SDL_TRUE, SDL_MapRGB(surface->format, 0xff, 0xff, 0xff));
        texture = SDL_CreateTextureFromSurface(*renderer, surface);
        if(!texture){
            printf("Failed to load image %s: %s\n", imgPath, SDL_GetError());
        }
        srcRect->w = surface->w;
        srcRect->h = surface->h;

        SDL_FreeSurface(surface);
    }
    return texture;
}

Texture loadImageTexture(SDL_Renderer **renderer, const char* imgPath){
    Texture texture;
    SDL_memset(&texture, 0, sizeof (Texture));
    SDL_Surface *surface = IMG_Load(imgPath);
    if(!surface){
        printf("Failed to load image %s: %s\n", imgPath, IMG_GetError());
    }else{
        SDL_SetColorKey(surface, SDL_TRUE, SDL_MapRGB(surface->format, 0xff, 0xff, 0xff));
        texture.texture = SDL_CreateTextureFromSurface(*renderer, surface);
        if(!texture.texture){
            printf("Failed to load image %s: %s\n", imgPath, SDL_GetError());
        }
        texture.w = surface->w;
        texture.h = surface->h;
        SDL_FreeSurface(surface);
    }
    return texture;
}

Texture loadImageTextureWithFormat(SDL_Window **win, SDL_Renderer **renderer, const char* imgPath){
    Texture texture;

    //The final texture
    SDL_Texture* newTexture = NULL;

    //Load image at specified path
    SDL_Surface* loadedSurface = IMG_Load(imgPath);
    if( loadedSurface == NULL )
    {
        printf( "Unable to load image %s! SDL_image Error: %s\n", imgPath, IMG_GetError() );
    }
    else
    {
        //Convert surface to display format
        SDL_Surface* formattedSurface = SDL_ConvertSurfaceFormat( loadedSurface, SDL_GetWindowPixelFormat( *win ), 0 );
        if( formattedSurface == NULL )
        {
            printf( "Unable to convert loaded surface to display format! SDL Error: %s\n", SDL_GetError() );
        }
        else
        {
            //Create blank streamable texture
            newTexture = SDL_CreateTexture( *renderer, SDL_GetWindowPixelFormat( *win ), SDL_TEXTUREACCESS_STREAMING, formattedSurface->w, formattedSurface->h );
            if( newTexture == NULL )
            {
                printf( "Unable to create blank texture! SDL Error: %s\n", SDL_GetError() );
            }
            else
            {
                //Lock texture for manipulation
                SDL_LockTexture( newTexture, NULL, &texture.pixels, &texture.pitch );

                //Copy loaded/formatted surface pixels
                memcpy( texture.pixels, formattedSurface->pixels, formattedSurface->pitch * formattedSurface->h );

                //Unlock texture to update
                SDL_UnlockTexture( newTexture );
                texture.pixels = NULL;

                //Get image dimensions
                texture.w = formattedSurface->w;
                texture.h = formattedSurface->h;
            }

            //Get rid of old formatted surface
            SDL_FreeSurface( formattedSurface );
        }

        //Get rid of old loaded surface
        SDL_FreeSurface( loadedSurface );
    }

    //Return success
    texture.texture = newTexture;
    return texture;
}

